\documentclass{report}

\usepackage[portuguese]{babel}
\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\usepackage{listings}
\usepackage{graphicx}
\usepackage{subfig}
\usepackage{float}
\usepackage{glossaries}
\usepackage{parskip}
\usepackage[top=3cm, bottom=2.5cm, left=3cm, right=3cm]{geometry}

% Document's properties.
\newcommand{\DocTitle}{Implementação Concorrente da API JDBC}
\newcommand{\DocAuthor}{Wilson Santos, 36228}
\newcommand{\DocSubject}{Dissertação de mestrado}
\newcommand{\DocKeywords}{JDBC, Native-protocol driver, Concurrency, SQL Server}

\setcounter{tocdepth}{2}      % depth of toc entries
\setcounter{secnumdepth}{5}   % depth of sections

\setlength{\parskip}{0.35cm}  % space between paragraphs
\setlength{\parindent}{6mm}   % indent space

\hypersetup{
    bookmarks=true,         % show bookmarks bar?
    unicode=false,          % non-Latin characters in Acrobat’s bookmarks
    pdftoolbar=true,        % show Acrobat’s toolbar?
    pdfmenubar=true,        % show Acrobat’s menu?
    pdffitwindow=true,      % page fit to window when opened
    pdftitle={\DocTitle},       % title
    pdfauthor={\DocAuthor},     % author
    pdfsubject={\DocSubject},   % subject of the document
    pdfkeywords={\DocKeywords}, % list of keywords
    pdfnewwindow=true,          % links in new window
    colorlinks=true,        % false: boxed links; true: colored links
    linkcolor=red,          % color of internal links
    citecolor=green,        % color of links to bibliography
    filecolor=magenta,      % color of file links
    urlcolor=cyan           % color of external links
}

\captionsetup{justification=centering,font=small}

\lstset{language=Java, numbers=left, numberstyle=\tiny, numbersep=5pt}

\DeclareGraphicsExtensions{.pdf,.png,.jpg}

% Glossary entries
\newglossaryentry{gls:bulkinsert} {
  name={bulk insert},
  description={Método eficiente de preenchimento de uma tabela, invocado por um cliente num servidor}
}
\newglossaryentry{gls:storedprocedure} {
  name={stored procedure},
  description={Sub-rotina constituídas por comandos T-SQL, disponível num sistema de base de dados relacional}
}
\newglossaryentry{gls:udf} {
  name={user defined function (UDF)},
  description={Função criada pelo utilizador que pode ser utilizada em instruções SQL}
}
\newglossaryentry{gls:odbc} {
  name={ODBC},
  description={\emph{\textbf{O}pen \textbf{D}ata\textbf{b}ase \textbf{C}onnectivity} fornece uma interface de software \emph{standard} para aceder a um \gls{gls:dbms}}
}
\newglossaryentry{gls:dbms} {
  name={DBMS},
  description={Um \emph{\textbf{D}ata \textbf{M}anagement \textbf{S}ystem} é um sistema que permite criar, gerir e utilizar uma base de dados}
}

\makeglossaries


\begin{document}

% Top matter
\title{\DocTitle}
\author{\DocAuthor \texttt{$<$wilson.santos@ua.pt$>$}\\
  Universidade de Aveiro}
\maketitle

\begin{abstract}
A definição da API JDBC não prevê uma utilização concorrente dos serviços disponibilizados pelas várias interfaces que a constituem. Por isso, os drivers que implementam a API, não possuem suporte para um acesso concorrente. 
Neste documento é descrita uma implementação concorrente de um driver para SQL Server 2008.
No final da implementação são realizados testes de desempenho que avaliam a sua performance em relação à implementação standard. 
\end{abstract}

\tableofcontents
\addcontentsline{toc}{section}{Conteúdo}

\listoftables
\addcontentsline{toc}{section}{Lista de tabelas}

\listoffigures
\addcontentsline{toc}{section}{Lista de figuras}

\pagebreak

\section*{Introdução}
\addcontentsline{toc}{section}{Introdução}

\pagebreak

\include{sec-architecture}

\section{JDBC Driver}
Um JDBC driver é um componente de software que implementa a \emph{\textbf{J}ava \textbf{D}ata\textbf{b}ase \textbf{C}onnectivity \textbf{A}PI}, permitindo assim às aplicações Java interagirem com uma base de dados.

Existem quatro categorias de driver\cite{SUNJDBCDRIVERS,WIKIJDBCDRIVERS}:
\begin{description}
  \item[1. JDBC-ODBC] \hfill \\
  Utiliza um driver \gls{gls:odbc} para estabelecer a comunicação.
  \item[2. Native-API] \hfill \\
  Converte os pedidos em chamadas a uma biblioteca cliente.
  \item[3. Network-Protocol] \hfill \\
  Utiliza uma camada intermédia cuja função é converter os pedidos na linguagem (protocolo) da base de dados.
  \item[4. Native-Protocol] \hfill \\
  Converte os pedidos directamente no protocolo utilizado pelo \gls{gls:dbms}.
\end{description}

\hfill

Este documento discute a implementação de um driver do \textbf{tipo 4}.

\newpage

\section{Tabular Data Stream}
O \emph{Tabular Data Stream} (TDS) é um protocolo da camada aplicação \cite{MSTDS,SYBASETDS} utilizado para transferir informação entre um servidor de base de dados e um cliente. Foi desenhado e desenvolvido em 1984 pela Sybase Inc. para ser utilizado no servidor SQL da empresa, e mais tarde foi também desenvolvido pela Microsoft para ser utilizado no Microsoft SQL Server \cite{ENOTETDS}.

\subsection{Mensagens}
Como qualquer protocolo de rede, o TDS efectua a comunicação usando troca de mensagens. Existem duas categorias de mensagens: mensagens do cliente e mensagens do servidor.

Resumidamente as \textbf{mensagens do cliente} são:
\begin{description}
  \item[Pre-login] \hfill \\
  \emph{Handshake} que tem de ocorrer antes do \emph{login}, e que configura alguns parâmetros tais como a encriptação.
  \item[Login] \hfill \\
  Mensagem que inicia o estabelecimento da comunicação com o servidor. Como resposta, o servidor informa o cliente se aceitou ou rejeitou o pedido de comunicação.
  \item[SQL Command] \hfill \\
  Mensagem que na zona de dados contém um comando SQL ou \emph{batch} de comandos SQL, representado numa \emph{String} codificada em Unicode.
  \item[SQL Command com Dados Binários] \hfill \\
  Mensagem que faz um pedido de execução de uma operação \emph{\gls{gls:bulkinsert}} usando um comando SQL seguido de dados binários. O comando também é representado numa \emph{String} codificada em Unicode.
  \item[Remote Procedure Call (RPC)] \hfill \\
  Mensagem que faz um pedido de execução de um \emph{\gls{gls:storedprocedure}} ou uma \emph{\gls{gls:udf}}. A mensagem contém o nome, opções e parâmetros do RPC.
  \item[Attention signal] \hfill \\
  Mensagem que cancela a execução de um comando.
\end{description}

\hfill

Resumidamente as \textbf{mensagens do servidor} são:
\begin{description}
  \item[Pre-login response] \hfill \\
  Resposta a uma mensagem de \emph{pre-login}.
  \item[Login response] \hfill \\
  Resposta a uma mensagem de \emph{login}. Contém informação sobre as características do servidor, informação opcional e mensagens de erro.
  \item[Row data] \hfill \\
  Resposta com os dados devolvidos pela execução de um comando. Esta mensagem é precedida por uma descrição dos nomes das colunas e dos tipos de dados.
  \item[Return status] \hfill \\
  Resposta com o valor do estado de um RPC. Também é usada para enviar o estado do resultado da execução de uma instrução T-SQL.
  \item[Return parameters] \hfill \\
  Resposta com os valores dos parâmetros de saída de um RPC.
  \item[Response completion] \hfill \\
  Resposta que indica o fim de um conjunto de resultados.
  \item[Error e Info] \hfill \\
  Resposta que transmite mensagens de erro ou mensagens informativas.
  \item[Attention Acknowledgment] \hfill \\
  Resposta que confirma a recepção de um cancelamento de execução de um comando.
\end{description}

\subsubsection{Pacotes}
Cada mensagem é constituída por um ou mais pacotes. Cada pacote tem um tamanho máximo cujo valor é determinado na mensagem de \emph{login}. Todos os pacotes da mensagem excepto o último têm de ter um tamanho igual ao valor do tamanho máximo negociado. Cada pacote é constituído por um cabeçalho (\emph{packet header}) e por uma zona de dados (\emph{packet data}).

\paragraph{Cabeçalho} 
\hfill

Corresponde aos primeiros \textbf{8 bytes} do pacote. Os campos do cabeçalho estão representados na seguinte tabela. O valor em cima de cada campo indica o número de bytes desse campo.

\begin{table}[H]
  \caption{Campos do cabeçalho}
  \label{tab:header-fields}
  \centering
\begin{tabular}{ *{6}{p{1.5cm}}}
  1 & 1 & 2 & 2 & 1 & 1
\end{tabular}
\\
\begin{tabular}{| p{1.5cm} *{4}{| p{1.5cm} } | p{1.5cm} |}
  \hline
  Type & Status & Length & SPID & PacketId & Window \\ \hline
\end{tabular}
\end{table}

\textbf{Descrição dos campos do cabeçalho}:
\begin{description}
  \item[Type] \hfill \\
  Define o tipo de mensagem.
  \item[Status] \hfill \\
  Indica o estado da mensagem (por exemplo, indica se a mensagem terminou).
  \item[Length] \hfill \\
  Indica o tamanho do pacote (incluindo o tamanho do cabeçalho).
  \item[SPID] \hfill \\
  Identifica o ID do processo no servidor correspondente à ligação actual. Este campo tem carácter opcional, pelo que nesta implementação será sempre enviado o valor \texttt{0x0000}.
  \item[PacketID] \hfill \\
  Indica o número do pacote. Cada pacote enviado incrementa este valor em uma unidade.
  \item[Window] \hfill \\
  Actualmente não é utilizado, por isso tem sempre o valor \texttt{0x00}.
\end{description}

\textbf{NOTA:} Todos os valores são representados em \emph{network byte order (big-endian)} e são valores sem sinal.

\paragraph{Zona de dados}
\hfill

Todos os tipos de mensagens, exceptuando a \emph{Attention signal}, a seguir ao cabeçalho têm uma zona de dados (\cite{MSTDS}  - secção 2.2.1.3.3).

\textbf{NOTA:} A zona de dados também pode ser denominada de \emph{data stream} ou apenas \emph{stream}.

Os pacotes tem um tamanho máximo, cujo valor é determinado no \emph{login}. O tamanho do pacote inclui o tamanho do cabeçalho. 

Se uma mensagem produzir um pacote que ultrapasse o tamanho definido, terá de ser dividida por múltiplos pacotes. Cada um desses pacotes terá um cabeçalho semelhante, exceptuando os campos \emph{Status} e \emph{Length}. O campo \emph{Status} terá o valor \texttt{0x0} se houverem mais pacotes da mensagem e terá o valor \texttt{0x1} se o pacote é o último da mensagem. O campo \emph{Length} terá um valor igual ao tamanho definido, para todos os pacotes excepto para o último da mensagem.

Existem dois tipos de zonas de dados: \textbf{\emph{Token Stream}} e \textbf{\emph{Tokenless Stream}}. Um \emph{token stream} é constituído por um ou mais \emph{tokens}, em que cada um deles é seguidos pelos dados relativos ao \emph{token}. Um \emph{tokenless stream} contém directamente os dados da mensagem, sem recorrer a \emph{tokens} para os descrever.

Na tabela a seguir temos um resumo das mensagens que usam \emph{tokens} e as que não usam.

\begin{table}[H]
  \caption{Indicação das mensagens que usam \emph{tokens}}
  \label{tab:token-vs-tokenless}
  \centering
\begin{tabular}{*{3}{| l } |}
  \hline
  \textbf{Mensagem} & \textbf{Origem} & \textbf{Token} \\ \hline
  Pre-Login                   & Cliente & Não \\ \hline
  Login                       & Cliente & Não \\ \hline
  SQL Batch                   & Cliente & Não \\ \hline
  Bulk Load                   & Cliente & Sim \\ \hline
  Remote Prodecure Call       & Cliente & Sim \\ \hline
  Attention                   & Cliente & Não \\ \hline
  Transaction Manager Request & Cliente & Não \\ \hline
  Pre-Login Response          & Servidor & ??? \\ \hline
  Login Response              & Servidor & Sim \\ \hline
  Row Data                    & Servidor & Sim \\ \hline
  Return Status               & Servidor & Sim \\ \hline
  Return Parameters           & Servidor & Sim \\ \hline
  Response Completion         & Servidor & Sim \\ \hline
  Error and Info Messages     & Servidor & Sim \\ \hline
  Attention Acknowledgment    & Servidor & Não \\ \hline
\end{tabular}
\end{table}

A definição da gramática dos \emph{streams} (\emph{token} e \emph{tokenless}) é especificada usando \emph{Augmented Backus-Naur Form} \cite{RFC4234}. Para obter um pequena descrição da ABNF consulte a secção \ref{sec:ABNF}

\paragraph{\emph{Tokenless Streams}}
\hfill

Um \emph{tokenless stream} contém directamente os dados da mensagem, sem recorrer a \emph{tokens} para os descrever.

A seguir é descrito o formato da zona de dados, das mensagens com \emph{tokenless streams}.

\subparagraph{Pre-Login}
\hfill

O \emph{stream} desta mensagem é constituído por uma sequência de opções seguidas dos dados relativos a essas opções. Cada opção tem três campos: \emph{Type}, \emph{Position} e \emph{Length}. \emph{Type} identifica a opção, \emph{Position} indica a posição que a opção ocupa nos dados e \emph{Length} indica o número de bytes que opção ocupa nos dados.

\begin{table}[H]
  \caption{Opções da mensagem de Pre-Login}
  \label{tab:pre-login-options}
  \centering
\begin{tabular}{*{3}{| l } |}
  \hline
  \textbf{Opção} & \textbf{Valor} & \textbf{Descrição} \\ \hline
  \texttt{VERSION}     & \texttt{0x00} & Versão do remetente. Normalmente usado para \emph{debugging}. \\ \hline
  \texttt{ENCRYPTION}  & \texttt{0x01} & Negociar encriptação. \\ \hline
  \texttt{INSTOPT}     & \texttt{0x02} & Nome da instância do SQL Server. \\ \hline
  \texttt{THREADID}    & \texttt{0x03} & Id do thread da aplicação cliente. Usado para \emph{debugging}. \\ \hline
  \texttt{TERMINATOR}  & \texttt{0xFF} & Assinala o fim da mensagem de Pre-Login. \\ \hline
\end{tabular}
\end{table}

Do que se conseguiu apurar apenas \texttt{VERSION} e \texttt{ENCRYPTION} são obrigatórios, e uma vez que as restantes opções de momento são irrelevantes, os pacotes de Pre-Login do driver só irão conter estas duas opções. Para além disso, ainda não será considerada a utilização de encriptação.

\paragraph{\emph{Token Streams}}
\hfill

% TODO

\newpage

\section{Implementação do driver}

Esta secção apresenta uma descrição das classes que implementam o JDBC driver.
Na tabela temos identificadas as classes que implementam as interfaces da API JDBC.

\begin{figure}[H]
  \caption{Diagrama das classes que implementam a API}
  \label{img:JDBC-impl}
  \centering
  \includegraphics[width=10cm]{./diagrams/JDBC-impl}
\end{figure}

\begin{table}[H]
  \caption{Sumário das classes que implementam as interfaces da API JDBC}
  \label{tab:jdbc-iface-impl}
  \centering
\begin{tabular}{*{2}{| l } |}
  \hline
  \textbf{Interface} & \textbf{Implementada por} \\ \hline
  \texttt{java.sql.Driver}     & \texttt{ConcurDriver} \\ \hline
  \texttt{java.sql.Connection}     & \texttt{ConcurConnection} \\ \hline
\end{tabular}
\end{table}

\textbf{NOTA:} Todas as classes acima enunciadas pertencem ao \emph{Java package}:

\texttt{ws.jdbc.concurrent.driver.sqlserver}

\subsection{Driver}

Quando uma aplicação que usa JDBC pede ao \emph{DriverManager} uma ligação através do método \texttt{getConnection}, ele procura um driver (entre os drivers registrados) que aceite o \texttt{url} fornecido. Depois invoca sobre o driver o método \texttt{connect}. Neste método o driver cria uma nova instância de uma ligação e devolve o objecto.

\subsection{Connection}

Como vimos na secção anterior a invocação do método \texttt{getConnection} acaba na criação de um objecto da ligação. Durante a criação do objecto é estabelecida uma ligação com o SQL Server através da troca de algumas mensagens, tal como está representado na Figura \ref{img:createConnection}.

\begin{figure}[H]
  \caption{Diagrama da criação de uma ligação}
  \label{img:createConnection}
  \centering
  \includegraphics[width=10cm]{./diagrams/createConnection}
\end{figure}

\newpage

\section{Implementação do TDS}

\begin{figure}[H]
  \caption{Diagrama de classes das mensagens do \emph{TDS}}
  \label{img:tds}
  \centering
  \includegraphics[width=10cm]{./diagrams/TDS}
\end{figure}

\newpage

\appendix
\section{Anexo - Augmented Backus-Naur Form}
\label{sec:ABNF}
A Augmented Backus-Naur Form é uma notação para definir formalmente uma gramática.

\subsection{Regras}
A gramática é definida através de regras. Uma regra tem a seguinte forma:

{\centering \texttt{nome = elementos crlf}

}

Em que \texttt{nome} é o nome da regra, \texttt{elementos} é uma ou mais regras ou um valor terminal, \texttt{crlf} é o indicador do fim da linha.
As regras são alinhadas à esquerda e se uma regra necessitar de mais de uma linha, as restantes linhas são indentadas.

\subsection{Valores terminais}
Um valor terminal corresponde a um ou mais caracteres numéricos. 
A base em que esses caracteres são representados é indicada explicitamente (por exemplo, 15$_{16}$ é representado por \texttt{\%x15}). A base é uma das seguintes:

\begin{center}
\begin{tabular}{ l }
  b = binária \\
  d = decimal \\
  x = hexadecimal
\end{tabular}
\end{center}

\subsection{Operadores}

\paragraph{Concatenação}
\hfill

A concatenação é realizada da seguinte forma:

{\centering \texttt{Regra1 = Regra2 Regra3}

}

\paragraph{Alternativas}
\hfill

A definição de alternativas é realizada da seguinte forma:

{\centering \texttt{Regra1 = Regra2 / Regra3}

}

\paragraph{Alternativas incrementais}
\hfill

A definição de alternativas incrementais é realizada da seguinte forma:

{\centering \texttt{Regra1 =/ \emph{alternativas}}

}

\paragraph{Gamas de valores}
\hfill

Uma gama de valores é definida da seguinte forma:

{\centering \texttt{\%c\#\#-\#\#}

}

Em que \texttt{c} representa a base, e os \texttt{\#} são os valores que definem a gama.

\paragraph{Grupo de sequências}
\hfill

Uma grupo de sequências é definida da seguinte forma:

{\centering \texttt{(Regra1 Regra 2)}

}

\paragraph{Repetição}
\hfill

Uma repetição é definida da seguinte forma:

{\centering \texttt{<a>*<b>elemento}

}


\printglossaries{}
\addcontentsline{toc}{section}{Glossário}

\bibliography{../../../../Libraries/mybib}{}
\addcontentsline{toc}{section}{Bibliografia}
\bibliographystyle{unsrt}

\end{document}
